Troubleshooting Undefined Components in MDX
This guide explains how to identify and fix build failures caused by using React components in .mdx files without importing or defining them.
1. The Build Failure
Symptoms
After adding or updating a .mdx file, the site shows a 502 Bad Gateway error. Unlike simple syntax errors, these often allow the Webpack compilation to finish but fail during the "Static Site Generation" (SSG) phase.
How to Diagnose
Check the container logs for Expected component ... to be defined:
sudo docker logs docusaurus | grep -A 10 "Expected component"
Common Error Message:
Error: Expected component Badge to be defined: you likely forgot to import, pass, or provide it.
2. The Cause
When you use a JSX tag like <Badge /> or <MyComponent /> inside an .mdx file, Docusaurus treats it as a React component. If that component is not:
- Imported from a file (e.g.,
import MyComponent from '@site/src/components/MyComponent'). - Defined inline using
export const .... - Provided globally via
MDXComponents.js.
...then the React renderer doesn't know what to do with it and throws an error during the build.
3. The Solution
Option A: Define Inline (Quick Fix)
If you just need a small component for one page, define it at the top of the file:
export const Badge = ({text, color = 'primary'}) => (
<span className={`badge badge--${color}`}>{text}</span>
);
- <Badge text="New" />
- <Badge text="Beta" color="warning" />
Option B: Import Docusaurus Components
Some components are built into Docusaurus but still need an explicit import in MDX:
import Link from '@docusaurus/Link';
- <Link to="/docs/intro">Go to Intro</Link>
Option C: Remove the Component
If you don't actually need the component, replace it with standard Markdown or HTML:
- **[New]** Item
4. Verification
After fixing the file, restart the container and monitor the logs:
sudo docker restart docusaurus
sudo docker logs -f docusaurus
Wait for: [SUCCESS] Serving "build" directory at: http://0.0.0.0:3000/.
If you still see a 502 error after a "SUCCESS" message, try restarting the tunnel:
sudo docker restart cloudflared